"""
日志工具封装模块
基于loguru实现，支持配置文件的完整日志功能
"""

import os
import sys
from pathlib import Path
from typing import Optional, Dict, Any
from loguru import logger
from pkg.settings.config import settings


class Logger:
    """
    日志管理器
    
    基于loguru实现的日志工具，支持：
    - 控制台输出
    - 文件输出（可配置）
    - 日志轮转
    - 自定义格式
    - 多级别日志
    """
    
    def __init__(self):
        """初始化日志配置"""
        self._configured = False
        self._logger = logger
        self._setup_logger()
    
    def _setup_logger(self):
        """配置日志设置"""
        if self._configured:
            return
        
        # 移除默认的控制台处理器
        self._logger.remove()
        
        # 根据配置添加控制台输出
        if settings.LOG_CONSOLE_OUTPUT:
            self._add_console_handler()
        
        # 根据配置添加文件输出
        if settings.LOG_FILE_ENABLED:
            self._add_file_handler()
        
        self._configured = True
    
    def _add_console_handler(self):
        """添加控制台输出处理器"""
        self._logger.add(
            sys.stdout,
            level=settings.LOG_LEVEL,
            format=settings.LOG_FORMAT,
            colorize=True,  # 控制台输出带颜色
            backtrace=True,
            diagnose=True
        )
    
    def _add_file_handler(self):
        """添加文件输出处理器"""
        # 确保日志目录存在
        log_file_path = Path(settings.LOG_FILE_PATH)
        log_file_path.parent.mkdir(parents=True, exist_ok=True)
        
        self._logger.add(
            settings.LOG_FILE_PATH,
            level=settings.LOG_LEVEL,
            format=settings.LOG_FORMAT,
            rotation=f"{settings.LOG_MAX_SIZE} MB",  # 按大小轮转
            retention=settings.LOG_BACKUP_COUNT,     # 保留的备份数量
            compression="zip",                       # 压缩旧日志文件
            encoding="utf-8",                        # 使用UTF-8编码
            backtrace=True,
            diagnose=True
        )
    
    def debug(self, message: str, **kwargs):
        """记录调试信息"""
        self._logger.debug(message, **kwargs)
    
    def info(self, message: str, **kwargs):
        """记录一般信息"""
        self._logger.info(message, **kwargs)
    
    def warning(self, message: str, **kwargs):
        """记录警告信息"""
        self._logger.warning(message, **kwargs)
    
    def error(self, message: str, **kwargs):
        """记录错误信息"""
        self._logger.error(message, **kwargs)
    
    def critical(self, message: str, **kwargs):
        """记录严重错误信息"""
        self._logger.critical(message, **kwargs)
    
    def exception(self, message: str, **kwargs):
        """记录异常信息（自动包含异常栈）"""
        self._logger.exception(message, **kwargs)
    
    def bind(self, **kwargs):
        """绑定上下文信息到日志"""
        return self._logger.bind(**kwargs)
    
    def with_context(self, **context) -> "Logger":
        """
        创建带有上下文信息的日志记录器
        
        Args:
            **context: 上下文键值对
            
        Returns:
            带有上下文的Logger实例
        """
        bound_logger = self._logger.bind(**context)
        new_logger = Logger.__new__(Logger)
        new_logger._logger = bound_logger
        new_logger._configured = True
        return new_logger
    
    def log_request(self, request_id: str, method: str, url: str, user_id: Optional[int] = None):
        """
        记录HTTP请求信息
        
        Args:
            request_id: 请求ID
            method: HTTP方法
            url: 请求URL
            user_id: 用户ID（可选）
        """
        context = {
            "request_id": request_id,
            "method": method,
            "url": url,
            "type": "request"
        }
        if user_id:
            context["user_id"] = user_id
        
        self._logger.bind(**context).info(f"收到请求: {method} {url}")
    
    def log_response(self, request_id: str, status_code: int, duration: float):
        """
        记录HTTP响应信息
        
        Args:
            request_id: 请求ID
            status_code: HTTP状态码
            duration: 请求处理时间（秒）
        """
        context = {
            "request_id": request_id,
            "status_code": status_code,
            "duration": duration,
            "type": "response"
        }
        
        level = "info"
        if status_code >= 400:
            level = "warning"
        if status_code >= 500:
            level = "error"
        
        getattr(self._logger.bind(**context), level)(
            f"请求完成: 状态码={status_code}, 耗时={duration:.3f}s"
        )
    
    def log_db_query(self, sql: str, params: Optional[Dict[str, Any]] = None, duration: Optional[float] = None):
        """
        记录数据库查询信息
        
        Args:
            sql: SQL语句
            params: 查询参数
            duration: 查询耗时（秒）
        """
        context = {"type": "db_query", "sql": sql}
        if params:
            context["params"] = params
        if duration:
            context["duration"] = duration
        
        message = f"数据库查询: {sql[:100]}..."
        if duration:
            message += f" (耗时: {duration:.3f}s)"
        
        self._logger.bind(**context).debug(message)
    
    def log_auth(self, user_id: int, action: str, result: str, details: Optional[str] = None):
        """
        记录认证相关日志
        
        Args:
            user_id: 用户ID
            action: 操作类型（login, logout, access等）
            result: 操作结果（success, failed, denied等）
            details: 详细信息
        """
        context = {
            "user_id": user_id,
            "action": action,
            "result": result,
            "type": "auth"
        }
        if details:
            context["details"] = details
        
        level = "info" if result == "success" else "warning"
        self._logger.bind(**context).__getattribute__(level)(
            f"认证操作: 用户{user_id} {action} {result}"
        )
    
    def log_business(self, module: str, operation: str, user_id: Optional[int] = None, **kwargs):
        """
        记录业务操作日志
        
        Args:
            module: 业务模块
            operation: 操作类型
            user_id: 用户ID
            **kwargs: 其他业务相关信息
        """
        context = {
            "module": module,
            "operation": operation,
            "type": "business"
        }
        if user_id:
            context["user_id"] = user_id
        context.update(kwargs)
        
        self._logger.bind(**context).info(f"业务操作: {module}.{operation}")


# 全局日志实例
_global_logger: Optional[Logger] = None


def get_logger() -> Logger:
    """
    获取全局日志实例
    
    Returns:
        Logger实例
    """
    global _global_logger
    if _global_logger is None:
        _global_logger = Logger()
    return _global_logger


def create_module_logger(module_name: str) -> Logger:
    """
    创建模块专用的日志记录器
    
    Args:
        module_name: 模块名称
        
    Returns:
        带有模块上下文的Logger实例
    """
    return get_logger().with_context(module=module_name)


# 便捷的模块级别函数
def debug(message: str, **kwargs):
    """记录调试信息"""
    get_logger().debug(message, **kwargs)


def info(message: str, **kwargs):
    """记录一般信息"""
    get_logger().info(message, **kwargs)


def warning(message: str, **kwargs):
    """记录警告信息"""
    get_logger().warning(message, **kwargs)


def error(message: str, **kwargs):
    """记录错误信息"""
    get_logger().error(message, **kwargs)


def critical(message: str, **kwargs):
    """记录严重错误信息"""
    get_logger().critical(message, **kwargs)


def exception(message: str, **kwargs):
    """记录异常信息"""
    get_logger().exception(message, **kwargs) 